package com.ego.product.interceptor;

import com.ego.common.constant.MemberConstant;
import com.ego.common.constant.SystemConstant;
import com.ego.common.to.member.MemberGroupTo;
import com.ego.common.to.member.MemberTo;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;

/**
 * @program: ego
 * @description: 购物车拦截器 —— 在执行目标方法前先判断用户的登录状态并封装传递给目标请求。
 *               要想使拦截器生效，不能仅仅使用@Component注解，需要在在webConfig中配置
 *               相关拦截器。
 * @see com.ego.product.config.WebConfig
 * @author: KamTang
 * @create: 2022-12-14 16:37
 **/
public class CartInterceptor implements HandlerInterceptor {

    public static ThreadLocal<MemberGroupTo> threadLocal = new ThreadLocal<>();

    /**
     * 目标方法执行之前
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        MemberGroupTo memberInfo = new MemberGroupTo();
        MemberTo loggedUser = (MemberTo) request.getSession().getAttribute(MemberConstant.LOGGED_USER);
        if (ObjectUtils.isNotEmpty(loggedUser)) {
            // 用户登录
            memberInfo.setUserId(loggedUser.getId());
        }
        Cookie[] cookies = request.getCookies();
        if (cookies != null && cookies.length > 0) {
            for (Cookie cookie : cookies) {
                if (MemberConstant.TEMP_USER_COOKIE_NAME.equals(cookie.getName())) {
                    memberInfo.setUserKey(cookie.getValue());
                    memberInfo.setTempUser(true);
                }
            }
        }

        // 如果没有userKey，也就是用户第一次进入网站也没有进行注册
        if (StringUtils.isEmpty(memberInfo.getUserKey())) {
            String uuid = UUID.randomUUID().toString();
            memberInfo.setUserKey(uuid);
        }

        // 目标方法执行之前
        threadLocal.set(memberInfo);
        return true;
    }

    /**
     * 目标方法执行之后，为临时用户分配cookie-key，让浏览器保存
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 保存一个临时用户
        if (!threadLocal.get().getTempUser()) {
            Cookie cookie = new Cookie(MemberConstant.TEMP_USER_COOKIE_NAME, threadLocal.get().getUserKey());
            cookie.setDomain(SystemConstant.COOKIE_DOMAIN_NAME);
            cookie.setMaxAge(MemberConstant.TEMP_USER_COOKIE_LIFETIME);
            response.addCookie(cookie);
        }
    }
}
